const cron = require('node-cron');
const TokenTransaction = require('../models/TokenTransaction');
const Visitor = require('../models/Visitor');
const { sequelize } = require('../config/database');
const { Op } = require('sequelize');

class TokenCleanupTask {
  constructor() {
    this.isRunning = false;
    this.task = null;
  }

  // 启动定时任务 - 每10分钟执行一次
  start() {
    if (this.task) {
      console.log('Token cleanup task is already running');
      return;
    }

    // 每10分钟执行一次清理
    this.task = cron.schedule('*/10 * * * *', async () => {
      await this.cleanupExpiredReservations();
    }, {
      scheduled: false
    });

    this.task.start();
    console.log('Token cleanup task started - running every 10 minutes');
  }

  // 停止定时任务
  stop() {
    if (this.task) {
      this.task.stop();
      this.task = null;
      console.log('Token cleanup task stopped');
    }
  }

  // 清理过期的预扣交易
  async cleanupExpiredReservations() {
    if (this.isRunning) {
      console.log('Cleanup already in progress, skipping...');
      return;
    }

    this.isRunning = true;
    const transaction = await sequelize.transaction();

    try {
      const now = new Date();
      console.log(`[${now.toISOString()}] Starting cleanup of expired token reservations...`);
      
      // 查找所有过期的预扣交易
      const expiredReservations = await TokenTransaction.findAll({
        where: {
          type: 'reserve',
          status: 'pending',
          expires_at: {
            [Op.lt]: now
          }
        },
        transaction,
        lock: transaction.LOCK.UPDATE
      });

      if (expiredReservations.length === 0) {
        console.log('No expired reservations found');
        await transaction.rollback();
        this.isRunning = false;
        return;
      }

      console.log(`Found ${expiredReservations.length} expired reservations to cleanup`);

      let cleanedCount = 0;
      let refundedTokens = 0;

      for (const reservation of expiredReservations) {
        const user_uuid = reservation.user_uuid;
        const amount = Math.abs(reservation.amount);

        // 获取用户信息并加锁
        const visitor = await Visitor.findOne({
          where: { uuid: user_uuid },
          transaction,
          lock: transaction.LOCK.UPDATE,
        });

        if (visitor) {
          // 解析原始扣除详情
          let originalDeductions = null;
          try {
            originalDeductions = reservation.metadata ? JSON.parse(reservation.metadata) : null;
          } catch (e) {
            console.warn('无法解析过期预扣记录的metadata:', reservation.id);
          }

          // 从tokenController导入按比例退还函数
          const { refundTokensProportionally } = require('../controllers/tokenController');
          
          // 按比例退还代币
          const newBalances = await refundTokensProportionally(visitor, amount, originalDeductions, transaction);

          // 直接更新原有预扣记录：状态、描述、金额（改为正数表示退还）、余额
          await reservation.update({
            status: 'canceled',
            description: `系统自动清理过期预扣_退还${amount}代币`,
            amount: amount, // 改为正数表示退还
            balance_after: newBalances.tokens_balance
          }, { transaction });

          cleanedCount++;
          refundedTokens += amount;
        }
      }

      await transaction.commit();

      console.log(`Cleanup completed successfully:`);
      console.log(`- Cleaned ${cleanedCount} expired reservations`);
      console.log(`- Refunded ${refundedTokens} tokens`);

    } catch (err) {
      await transaction.rollback();
      console.error('Failed to cleanup expired reservations:', err.message);
    } finally {
      this.isRunning = false;
    }
  }

  // 手动执行清理（可供API调用）
  async manualCleanup() {
    return await this.cleanupExpiredReservations();
  }

  // 获取任务状态
  getStatus() {
    return {
      isScheduled: !!this.task,
      isRunning: this.isRunning
    };
  }
}

// 导出单例
const tokenCleanupTask = new TokenCleanupTask();
module.exports = tokenCleanupTask;